/**@description ccay 验证组件，包含数据验证与form验证，并与原有jquery.validate验证保持兼容
 */
 
(function($){
	
Ccay.UI.Config.typeRule = {
	required: {required: true}, //必填验证
	number: {number: true}, //数字校验，可包含小数点或负数
	floatRequ:{number:true},//数字类型（不截取）
	integer: {digits: true},
	currency: {number: true},
	date: {date: true},
	datetime: {datetime: true},
	datehm: {datetime: true},
	dateym: {dateym:true},
	rate: {number: true, max: 1, min: 0}, 
	email: {email: true},
	url: {url: true},  
	digits: {digits: true}, // 可包含0与正整数
	speczh :{speczh : true},// 非特殊字符校验规则
	specialch :{specialch : true}, //非特殊字符校验，非中文校验 可包含"."
	specialch2 :{specialch2 : true},//非特殊字符校验，非中文校验 不可包含"."
	filesize : {filesize : true}	//文件size验证，可包含单位 b k m g t
};
var Helper;
var DataValidator = Ccay.DataValidator = $.IObject("dataValidator",Helper = {
	init : function(op){
		return $.extend(this,{
			ignore : true,  //配置为true，则验证时候，默认忽略错误，直到所有field验证执行完成
			fields : {},  //初始字段map
			context : {} //初始化上下文对象
		}, op);
	},
	
	/** 添加单个字段（Field） 的具体验证规则集合
	 * @param field {string} 字段名称      例如 ："name"
	 * @param rules {object} 具体配置规则  例如 ：{required : true, maxlength: 20}
	 */
	addField : function(field, rules){
		this.fields[field] = rules;
		return this;
	},
	/** 通过对象自变量，一次性添加多个字段的验证规则配置 例如 {name : {required : true, maxlength: 20}, age : { max :100}....}
	 * @param ruleOp {object} 规则配置对象
	 */
	addFields : function(ruleOp){
		this.fields = $.extend(this.fields, ruleOp);
		return this;
	},
	/**移除单个字段的验证规则
	 * @param field {String} 字段名称
	 */
	removeField : function(field){
		if( field in this.fields){
			delete this.fields[field];
		}
		return this;
	},
	
	/** 清楚验证器中所有的字段与验证规则配置 */
	clear : function(){
		this.fields = {};
		return this;
	},
	
	/** 设置验证器的执行规则，是否忽略field的验证错误
	 * @param bool {boolean} 是否忽略错误
	 */
	setIgnore : function(bool){
		this.ignore = !!bool;
	},
	
	/** 设置上下文对象
	 * @param context {object} 字段名称
	 */
	setContext : function(context){
		this.context = context;
	},
	
	/** 推荐外部调用的验证接口， 具有验证单个字段 valid(field, value)，或验证所有字段valid(valueObj)两个重载方式.
	 * @param field {String} 字段名称
	 * @param value {String} 值
	 * @return ret {boolean|string|object} 根据实际验证结果，返回true 、验证消息 或 验证错误消息集合 {name : "名称过长", age :"年龄不和规范"}
	 */
	valid : function(field, value){
		if(field && typeof field == "object"){
			return this.validFields(this.fields, field)
		}else{
			return this.validField(field, value);
		}
	},
	
	/** 一次性验证多个字段,根据实际验证结果，返回true 或 验证错误消息集合 {name : "名称过长", age :"年龄不和规范"}
	 * @param fields {object} 字段名称的map集合
	 * @param values {object} 值或值的集合
	 * @return ret {boolean|object} true 或 错误消息集合
	 */
	validFields : function(fields ,values){
		var msg = true, errors = {};
		for( var field in fields){
			//将数据集对象当作上下文，传给单个数据验证方法
			msg = this.validField(field, Ccay.DataHelper.getObj(field, values),values);
			if(msg !== true){
				errors[field] = msg;
			}
			if(!this.ignore && msg !== true){
				return errors;
			}
		}
		return $.isEmptyObject(errors) ? true : errors;
		
	},
	
	
	/** 验证单个字段,根据实际验证结果，返回true 或 验证错误提示消息
	 * @param fields {object} 字段名称的map集合
	 * @param values {object} 值或值的集合
	 * @return ret {boolean|string} true 或 错误消息
	 */
	validField : function(field, value, context){
		if(field in this.fields){
			var rules = this.fields[field];
			return this.validValue(value, rules, context, field);
		}
		return true;
	},
	
	validValue: function(value, rules, context, field){
		if(typeof(value)!="object"){ 
			value = $.trim(value);
		}
		//优先验证required ，当值为空的情况下，如需要验证required，则返回必填错误消息，否则验证成功，无需要验证其他
		
		if(Ccay.DataHelper.isEmpty(value)){
			if(rules.required){
				return Helper.getMessage.call(this, field, "required",context);
			}else{
				for(var rule in rules){
					var method = typeof rules[rule] =="function" ? rules[rule] : Methods[rule];
					if(rule == "customRequired" ||  method && method.required){
						var ret = method.type =="old-version" ?  method.call(this, value, context, ruleParam) : method.call(this, value,ruleParam,context);
						if(ret !== true){
							return typeof ret == "string" ? ret : Helper.getMessage.call(this, field, rule,context);
						}
					}
				}
				return true;
			}
		}
		var ruleParam, method, ret = true;
		for(var rule in rules){
			//拿到当前规则的参数 比如 minlength : 4  与 rangelength :[10,20]中配置的实际参数
			ruleParam= rules[rule], method= null;
			//如果参数是一个验证函数，则用该函数作为验证方法
			if(typeof ruleParam == "function"){
				method = ruleParam; 
			}
			//如果不是自定义验证，则从框架内部自带的验证方法中获取
			if(!method){
				method = Methods[rule];
			}
			//修复customRequired校验不是必填找不到customRequired方法
			if(rule == "customRequired"){
				method = rules[rule];
				ret =  method.call(this, value,ruleParam,context);
				if(ret !== true){
					return ret; 
				}
			}
			
			//如果获取到验证方法，则进行验证
			if(method){
				//判断验证方法是否是原有验证接口添加，如果是，则执行原有验证接口参数适配，兼容老版本
				if(method.type =="old-version"){ 
					ret = method.call(this, value, context, ruleParam);
					if(ret === false){
						ret = typeof Messages[rule] =="function" ?  Messages[rule].call(this, ruleParam, context) : (Messages[rule] || "Warning: No message defined for " + rule) 
					}else if(ret === "pending"){
						ret = Messages.remote;
					}
					if(ret !== true){
						return ret;
					}
				}else{
					//新方式验证接口
					ret = method.call(this, value, ruleParam, context);
					if(ret === "pending"){
						ret = Messages.remote;
					}
				}
			}else if(Ccay.UI.Config.typeRule[rule]){
				ret = this.validValue(value, Ccay.UI.Config.typeRule[rule], context, field);
				if(ret !== true){
					return ret;
				}
			}
			if(ret !== true){
				return Helper.getMessage.call(this, field, rule, ruleParam, context);
			}
		}
		return ret;
	},
	
	/** 通过字段名称与规则配置，获取到错误消息
	 */
	getMessage : function(field, rule, params, context){
		var message, params, msgs ;
		if(this.__type =="iobject" && this.fields[field]){
			params = this.fields[field][rule];
			msgs = this.fields.messages;
		}
		//获取到自定义的消息配置
		if(msgs){
			message = msgs[field + "-" + rule] || msgs[rule];
		}
		//如果没有自定义消息配置，则使用框架规则错误消息配置，如都没有配置，则提示warning！
		if(!message){
			message = Messages[rule] || "Warning: No message defined for " + rule;
		}
		
		var type =  typeof message;
		if(type == "function"){
			message = message.call(this, params, context);
		}
		
		if(typeof message == "string"){
			if($.isArray(params)){
				message = message.formatValue.apply(message,params)
			}else{
				message =message.formatValue(params);
			}
		}
		return message;
	}
});

var FormValidator = Ccay.FormValidator = $.IObject("formValidator", {
	
	
	normalizeRules: function(rules) {
		// 检查验证规则信息，忽略为false的规则
		$.each(rules, function(prop, val) {
			if (val === false) {
				delete rules[prop];
			}
		});
		// clean number parameters
		$.each(['minlength', 'maxlength', 'min', 'max'], function() {
			if (rules[this]) {
				rules[this] = Number(rules[this]);
			}
		});
		$.each(['rangelength', 'range'], function() {
			if (rules[this]) {
				rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
			}
		});

		// 自动创建区间规则
		if (rules.min && rules.max) {
			rules.range = [rules.min, rules.max];
			delete rules.min;
			delete rules.max;
		}
		if (rules.minlength && rules.maxlength) {
			rules.rangelength = [rules.minlength, rules.maxlength];
			delete rules.minlength;
			delete rules.maxlength;
		}
		return rules;
	},

	
	// 返回元素的样式规则配置集合
	classRules: function(elmt) {
		var rules = {};
		var classes = elmt.attr("class");
		classes && $.each(classes.split(" "), function() {
			if (this in Ccay.UI.Config.typeRule) {
				rules[this] = true;
			}
		});
		return rules;
	},
	
	//返回元素的属性配置验证规则集合
	attributeRules: function(elmt) {
		var rules = {};
		for (var method in Methods) {
			var value = elmt.attr(method);
			if (value) {
				rules[method] = value;
			}
		}
		return rules;
	},
	
	check : function(elmt, async){
		var rules = $.extend({},this.fields[elmt.prop("name")], this.classRules(elmt));
		var attrRules = this.attributeRules(elmt);
		if(attrRules.url){
			delete attrRules.url;
		}
		$.extend(rules, attrRules); 
		
		rules = this.normalizeRules(rules);
		
		var value = elmt.data("placeholder") != elmt.val() ? elmt.val() : "";
		var ret = this.validValue(value, rules, elmt);
		//如果是单个控件必填验证，并且从未进行panel级别的验证，则 必填提示信息不提示
		if(this.checkType == "unit" &&  ret == Messages.required && !this.valided && this.focusoutValid){
			return ret;
		}
		if(this.checkType !== "unit" || ret !== Messages.remote){
			if(typeof ret == "string" && elmt.hasClass("ccay-calendar") && elmt.attr("format") && !Ccay.Config.Format[elmt.attr("format")]){
				var format = elmt.attr("format").split(" ")[0],retMatch = ret.match(/(\d{4})-(\d{1,2})-(\d{1,2})/);
				if(retMatch){
					retMatch.shift();
					ret = ret.replace(/(\d{4})-(\d{1,2})-(\d{1,2})/,format.replace("yyyy",retMatch[0]).replace("MM",retMatch[1]).replace("dd",retMatch[2]));
				}else{
					retMatch = ret.match(/(\d{4})-(\d{1,2})/);
					if(retMatch){
						retMatch.shift();
						ret = ret.replace(/(\d{4})-(\d{1,2})/,format.replace("yyyy",retMatch[0]).replace("MM",retMatch[1]));
					}
				}
				//ret = 
			}
			this.showLabel(elmt, ret);
		}
		
		return ret;
	}, 
	
	showLabel : function(elmt, message){
		var errorLbl = elmt.next("label.error");

		if(message === true){
			elmt.removeClass("error-ctr");
			errorLbl.hide();
			if(typeof this.success == "function"){
				 this.success( errorLbl )
			}
		}else if(message ===""){
			errorLbl.hide();
		}else{
			var position = elmt.position(), width = elmt.outerWidth();
			if(errorLbl.length == 0){
				errorLbl = $.create("label","error").click(function() {
					$(this).hide().addClass('er-handle');
				});
			}
			errorLbl.html(message).css({top : position.top, left : position.left + width + 5});
			if(typeof this.errorPlacement == "function"){
				 this.errorPlacement(errorLbl, elmt.addClass("error") )
			}
			errorLbl.show();
		}
	}
	

	
	
}, new DataValidator());

Ccay.Validator = $.validator = {
	create : function(ruleOp){
		var validator;
		if(ruleOp && ruleOp.type == "form"){
			validator = new Ccay.FormValidator(ruleOp);
		}else{
			validator = new Ccay.DataValidator(ruleOp);
		}
		return validator;
	},
	
    addRule : function(ruleName,fn,message){
		Methods[ruleName] = fn;
		if(message){
			Messages[ruleName] = message;
		}
		var rule = {};
		rule[ruleName] = true;
		Ccay.UI.Config.typeRule[ruleName] = rule;
	},
	
	addClassRules : function(ruleName, rule){
		Ccay.UI.Config.typeRule[ruleName] = rule;
	},
	
    removeRule : function(ruleName,fn,message){
		Methods[ruleName] = null;
		Messages[ruleName] = null;
		Ccay.UI.Config.typeRule[ruleName] = null;
	},
	addMethod : function(){
		if(typeof arguments[1] == "function"){
			arguments[1].type = "old-version"
			if(arguments[3] == "required"){
				arguments[1].required =true;
			}
		}
		this.addRule.apply(this,arguments);
	},
	
	messages : {},
	format : function(){},

	valid : function(value, rules, context){
		return Helper.validValue(value, rules, context)
	}
	
};



$.fn.validate = function(op){
	
	if(this.is("form")){
		this.attr('novalidate', 'novalidate');
	}
	if(op){
		op.type = "form";
	}
	var validator = Ccay.Validator.create(op);
	this.data("validator", validator); 
	if(!this.hasClass("validate-context")){
		//igrid中编辑器有一次验证，所以在这里排除多余的一次验证。
		this.addClass("validate-context").delegate(":input:not(.grid-editor)","focusout", function(e){
			var input = $(this);
			if(!input.is(":button")){
				if(input.hasClass("ccay-suggest") || input.hasClass("ccay-user")){
					setTimeout(function(){input.valid("focusout")},0)
				}else{
					input.valid("focusout");
				} 
			}
		})
	}
};

/** 外部表单或元素验证接口。 
 * 做验证的时候需要区分（checkType）容器验证，还是单个组件的验证，根据类型的不同，需要对pending做不同的处理，
 * 单个验证（焦点失去）时，不需要对pending状态作出提示，继续等待验证即可， 容器验证，则需要将pending状态提示给用户，阻止表单提交
 */
$.fn.valid = function(param){
	 
	var validator, elmts = [], result = true, checkType = "unit";
	
	if(this.hasClass("validate-context")){
		validator = this.data("validator");
		elmts = this.find(":input");
		checkType = "container";
		$(this).triggerHandler("invalid-form", [this]);
		validator.valided = true;
	}else if( (elmts = this.filter(":input")).length > 0){
		validator = this.parents(".validate-context").data("validator");
	}
	var focusElmt = null;
	//如果有validator
	if(validator){
		validator.focusoutValid =  param == "focusout" ? true : false;
		validator.checkType = checkType;
		$.each(elmts, function(){
			var elmt = $(this);
			if(!elmt.is(":visible") && elmt.parents(".ccay-hideValid").length == 0){
				return;
			}
			if(validator.check(elmt) !== true){
				result = false;
				!focusElmt && (focusElmt = elmt);
			}
		});
	}
	this.is("form") && focusElmt && focusElmt.focus();
	return result;

};

$.fn.clearValid = function(){
	this.removeClass("error error-ctr").next("label.error").hide();
};

var Methods = {
	// 必填
	required: function(value) {
		return !Ccay.DataHelper.isEmpty(value);
	},
	
	regular : function(value, reg){
		return  reg.test(value);
	},
	// 最小长度
	minlength: function(value, param) {
		return value.getLength() >= param;
	},

	// 最大长度
	maxlength: function(value, param) {
		return value.getLength() <= param;
	},

	// 长度范围param[min,max]
	rangelength: function(value, param) {
		var length = value.getLength();
		return ( length >= param[0] && length <= param[1] );
	},

	// 数字最小值
	min: function( value, param ) {
		return value >= param;
	},

	// 数字最大值
	max: function( value, param ) {
		return value <= param;
	},

	// 值范围[min, max]
	range: function( value, param ) {
		return ( value >= param[0] && value <= param[1] );
	},

	// 邮箱验证
	email: function(value) {
		// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
		return (/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value));
	},

	// url
	url: function(value) {
		// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
		return (/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value));
	},

	// 日期格式
	date: function(value,param,input) {
		if(typeof(value) == "object" && !isNaN(value)){
			return true;
		}else{
			var format = !$.isPlainObject(input) ? input.attr("format") : null;
			format = !format || !Ccay.Config.Format[format] ? format : null;
			return value.validDate(format);
		}
		///^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
	},
	
	dateym : function(value,param,input){
		if(typeof(value) == "object" && !isNaN(value)){
	            return true;
	    }
		var reg = /^(\d{4})(-|\/)(\d{1,2})$/;
		var format = !$.isPlainObject(input) ? input.attr("format") : null;
		if(reg.test(value)){
			var arr = value.match(reg);
			if(arr[3] * 1 <= 12 )
				return true
		}else if(format && format!="date" && format!="datetime" && format!="dateym"){
			return value.validDate(format);
		}
		return false;
	},

	// 带时间日期格式
	datetime: function(value,param,input) {
		if(typeof(value) == "object" && !isNaN(value)){ 
			return true;
		}else{
			var format = !$.isPlainObject(input) ? input.attr("format") : null;
			format = !format || !Ccay.Config.Format[format] ? format : null;
			return value.validDate(format,1);
		}
	},
	
	// 数字
	number: function(value) {
		return (/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value));
	},

	// 整数验证
	digits: function(value) {
		return (/^\d+$/.test(value));
	},
	

	// 验证相同后缀名的字符串
	accept: function(value, param) {
		param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";
		return new RegExp(".(" + param + ")$").test(value);
	},

	// 验证两个输入框的值是否相同
	equalTo: function(value, targetValue) {
		return value == targetValue;
	},
	
	speczh : function(value){
		return !(new RegExp("[<>?!@#$%\\\\\\/]+").test(value));
	},
	specialch : function(value){
		return new RegExp("^[a-zA-Z0-9_.-]+$").test(value);
	},
	specialch2 : function(value){
		return new RegExp("^[a-zA-Z0-9_-]+$").test(value);
	},
	
	filesize : function(value, param){
		var unit = param[0], minsize = param[1], maxsize = param[2];
		if(/^\d+\.?\d*[BKMGT]?$/i.test(value)){
			var currUnit =value[value.search(/[BKMGT]/i)] || unit;
			value = Ccay.Format.toFileSize(parseFloat(value), unit, currUnit.toUpperCase()) || 0;
			return parseFloat(value) <= (max || 999999999) &&  parseFloat(value) >= ( min || 0 );
		}else{
			return false;
		}
	},
	
	// 远程校验
	remote: function(value, param) {

	}
	
	
};

/** 验证错误异常信息
 */
var Messages = {
	required: $i18n("ccay.common.validate.required"),
	remote: $i18n("ccay.common.validate.remote"),
	email:  $i18n("ccay.common.validate.email"),
	url:  $i18n("ccay.common.validate.url"),
	number: $i18n("ccay.common.validate.number"),
	digits: $i18n("ccay.common.validate.digits"),
	equalTo: $i18n("ccay.common.validate.equalto"), 
	accept: $i18n("ccay.common.validate.accept"),
	maxlength: function(param){
		return $i18n("ccay.common.validate.maxlength").replace("{-1}",Math.floor(param/3));
	},
	minlength:$i18n("ccay.common.validate.minlength"),
	rangelength: $i18n("ccay.common.validate.rangelength"),
	range: $i18n("ccay.common.validate.range"),
	max:$i18n("ccay.common.validate.max"),
	min: $i18n("ccay.common.validate.min"),
	dateCompare: $i18n("ccay.common.validate.dateCompare"),
	dateCompareB: $i18n("ccay.common.validate.dateCompareB"),
	date: $i18n("ccay.common.validate.date").formatText(new Date().format(Ccay.Config.Format.date)),
	datetime: $i18n("ccay.common.validate.datetime").formatText(new Date().format(Ccay.Config.Format.datehm)),
	dateym: $i18n("ccay.common.validate.dateym").formatText(new Date().format(Ccay.Config.Format.dateym)),
	dateISO: $i18n("ccay.common.validate.datetime").formatText(new Date().format(Ccay.Config.Format.datetime)),
	speczh: $i18n("ccay.common.validate.speczh"),
	specialch: $i18n("ccay.common.validate.specialcharacter"),
	specialch2: $i18n("ccay.common.validate.specialcharacter2"),
	filesize :  $i18n("ccay.common.validate.filesize"),
	sameValue :  $i18n("ccay.common.validate.sameValue"),
	"ccay-user":function(param, element){
		return $i18n("ccay.common.validate.ccayUser").format($(element).attr("error_msg") || "");
	},
	"ccay-suggest": function(param, element){
		return $i18n("ccay.common.validate.ccaySuggest").format($(element).attr("error_msg") || "");
	},
	"max-gap" : function(param, element){
		return $i18n("ccay.common.validate.dateInterval").formatText($(element).attr("maxGap") || "");
	},
	"ccay-combobox": $i18n("ccay.common.validate.combobox")
};


})(jQuery);

